﻿using System;
using System.IO;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using O1;
using O1.Data;
using O1.Data.Traversal;
using O1.IO;

namespace Tests.O1.Data.Traversal
{
    [TestClass]
    public class CellIteratorTests
    {
        [TestMethod, TestCategory("Unit Test")]
        public void CellIteratorIteratesExpectedDataFromBuffer()
        {
            var builder = new CellBuilder();
            BuildFakeCell(builder);
            
            var expectedFirstOffset = builder.Length;
            BuildFakeCell(builder);

            var expected = builder.ToArray();

            var filter = new CellBuilder();
            var observer = new CellObserver(filter);
            var offset = CellIterator.Iterate(1, expected, observer);
            offset.Should().Be(expectedFirstOffset);

            CellIterator.Iterate(1, expected, offset, observer);

            var actual = filter.ToArray();
            actual.Should().ContainInOrder(expected);
        }

        [TestMethod, TestCategory("Unit Test")]
        public void CellIteratorIteratesExpectedDataFromStream()
        {
            var builder = new CellBuilder();
            BuildFakeCell(builder);
            BuildFakeCell(builder);

            var expected = builder.ToArray();
            using (var adapter = new InputStreamAdapter(new MemoryStream(expected), expected.Length, true))
            {
                var filter = new CellBuilder();
                var observer = new CellObserver(filter);
                CellIterator.Iterate(0, adapter, observer);
                CellIterator.Iterate(0, adapter, observer);

                var actual = filter.ToArray();
                actual.Should().ContainInOrder(expected);
            }
        }

        private static void BuildFakeCell(CellBuilder builder)
        {
            builder.CheckVersion(new CellVersion(1L, 2L));
            builder.StartVertex(new CellAddress(1, 11111));
            builder.Evaluate(new DateTimeProperty(20, DateTimeOffset.UtcNow));
            builder.StartEdge(new Edge(8, 88888, 1), EdgeDirections.Outbound);
            builder.Evaluate(new Int32Property(123, 876));
            builder.EndEdge(ObservationInterests.Interested);
            builder.EndVertex(ObservationInterests.Interested);
        }
    }
}
